/**
 * @author: Christopher Rabotin
 * Conçu pour gérer toutes les communications au sein du programme.
 */

#ifndef COMMUNICATION_H_
#define COMMUNICATION_H_ 
#include "../src/casual_includes.h"
#include <unistd.h>
#include <sys/types.h> 
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h> 
#include <sys/wait.h>
#include <netdb.h> 

#include "message.h"

#define MAXRECVDATA 1024 /* nombre de serveurs à être initialisés */
#define PORT_INTERBOURSIER 1200 /* port du serveur interboursier. Tous les autres serveurs créé */
/**
 * TYPE permet de différencier les types de modules.
 * Il est utilisé partout dans la librairie de communication.
 */
enum TYPE {
	ack, /** ack: type acquisition */
	exec, /** exec: type exécution */
	term, /** term: type terminal (important car très différent des autres) */
	interb /** interb: type interboursier */
};

/**
 * server comprend toutes les données nécessaires au bon fonctionnement d'un serveur.
 * Attention, ici le terme "serveur" est un abus de langage puisque même un terminal est considéré
 * comme un serveur alors que, comme en témoigne le code de init_server(), terminal est bel et bien
 * un client (établie une connexion au lieu d'en attendre une).
 */
typedef struct server_struct {
	/** permet de savoir si le serveur tourne ou non */
	int isAlive;
	/** nom du serveur (Acquisition, Execution, Terminal) */
	char name[128];
	/** descripteur du socket */
	int sockfd;
	/** port du serveur*/
	int my_port;
	/** nombre maximal de connexions */
	int max_conn;
	/** nombre d'octets reçus par une connexion */
	int numbytes;
	/** taille du socket */
	socklen_t sin_size;
	/** adresse locale */
	struct sockaddr_in local_addr;
	/** adresse distante*/
	struct sockaddr_in remote_addr;
	/** données reçues */
	msg *recvdata;
} server;

/**
 * module comprend quelques informations permet d'identifier les modules entre-eux
 */
typedef struct module_struct {
	/** permet de stocker dans le module le serveur associé */
	server *srv;
	/** distingue les modules par leur type (voir l'enum TYPE) */
	int type;
	/** nom du module */
	char name[128];
	/** bourse dans lequel le module est intégré */
	int bourse_id;
} module;

/**
 * Permet d'initialiser un module
 * @param nom le nom du module
 * @param type le type du module: voir l'enum TYPE
 * @param bourse la bourse dans laquelle est placé le module
 */
module* init_module(char *nom, int type, int bourse);
/**
 * Permet de logguer les communications des serveurs. Placé dans communication.h puisque
 * utilisé uniquement pour la communication par socket.
 * @param srv le serveur d'où le log émane
 * @param un_msg message d'explication lié à l'ordre de transaction 
 */
void log_srv(const server* srv, char* un_msg);

/**
 * Permet de logguer les messages reçus par les serveurs. Placé dans communication.h puisque
 * utilisé uniquement pour la communication par socket.
 * @param srv le serveur d'où le log émane
 * @param damsg le message reçu
 * @param un_msg message d'explication lié à l'ordre de transaction 
 */
void log_msg_srv(const server* srv, msg* damsg, char* un_msg);

#endif /*COMMUNICATION_H_*/
